#ifndef TASK_STATE_MACHINE_H
#define TASK_STATE_MACHINE_H

#include <QMap>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QVector>

extern const int COMPOSITE_TASK_SPIKE_RECOVERY;  // 加标回收任务
extern const int COMPOSITE_TASK_ANALYSIS;        // 水样测量任务

/**
 * @brief 单步操作枚举
 * 系统的基础原子操作
 */
enum class AtomicOperation {
    IDLE = 0,                    // 空闲状态
    PREPROCESS = 1,              // 预处理
    ALGAE_REMOVAL = 2,           // 除藻
    ZERO_CHECK = 3,              // 零点核查
    STD_CHECK = 4,               // 标液核查
    CALIB_FULL = 5,              // 校正标定（完整）
    SPIKE_INTAKE = 6,            // 加标仪抽水
    SPIKE_ANALYSIS = 7,          // 加标测量
    SPIKE_DRAIN = 8,             // 加标仪排水
    SAMPLE_INTAKE = 9,           // 采样仪抽水
    ANALYSIS = 10,               // 水样测量
    SAMPLE_DRAIN = 11,           // 采样仪排水
    CLEAN = 12,                  // 仪表清洗
    STOP_DEVICE = 13,            // 停止设备
    PRE_SPIKE_VALVE_OPEN = 14,   // 开加标阀
    PRE_SPIKE_VALVE_CLOSE = 15,  // 关加标阀
    SPIKE_RECOVERY_FULL = 16,    // 完整加标回收流程
};

/**
 * @brief 步骤执行状态
 */
enum class StepState {
    PREPARING,  // 准备阶段：等待设备空闲，尝试启动操作
    EXECUTING,  // 正在执行操作：监控设备变繁忙
    WAITING,    // 等待条件满足
    COMPLETED   // 步骤完成
};

/**
 * @brief 操作步骤结构
 */
struct OperationStep {
    AtomicOperation operation;  // 要执行的原子操作
    QStringList targetDevices;  // 目标设备列表（空表示所有可操作设备）
    int executeTimeout;         // 执行超时时间（秒）- 设备操作执行超时
    QString waitForStatus;      // 等待的目标状态（空表示等待空闲，其他表示等待指定状态）
    int waitTimeout;            // 等待状态超时时间（秒）- 等待设备达到目标状态的超时时间
    QString description;        // 步骤描述
    QString conditionKey;       // 条件键名（空表示无条件执行，非空表示条件执行）
    bool abortOnError;          // 出错时是否终止任务（默认false）

    OperationStep(AtomicOperation op = AtomicOperation::IDLE,
                  const QStringList& devices = QStringList(), int executeTimeout = 10,
                  const QString& waitStatus = "", int waitTimeout = 0, bool abortOnError = false)
        : operation(op),
          targetDevices(devices),
          executeTimeout(executeTimeout),
          waitForStatus(waitStatus),
          waitTimeout(waitTimeout),
          abortOnError(abortOnError)
    {
    }
};

/**
 * @brief 复合任务定义
 */
struct CompositeTask {
    QString name;                  // 任务名称
    QVector<OperationStep> steps;  // 操作步骤序列（顺序执行）
    QString description;           // 任务描述

    CompositeTask(const QString& taskName = "") : name(taskName) {}
};

/**
 * @brief 简化的任务状态机
 * 基于单步操作的顺序执行任务管理器
 */
class TaskStateMachine : public QObject
{
    Q_OBJECT

public:
    explicit TaskStateMachine(QObject* parent = nullptr);
    ~TaskStateMachine();

    // 状态机控制
    void start();
    void stop();
    bool isRunning() const { return m_isRunning; }

    // 任务定义和管理
    void defineCompositeTask(int taskCode, const CompositeTask& task);
    bool hasCompositeTask(int taskCode) const;
    CompositeTask getCompositeTask(int taskCode) const;
    QList<int> getAvailableTasks() const;

    // 任务执行
    bool executeTask(int taskCode);
    bool executeAtomicOperation(AtomicOperation operation,
                                const QStringList& devices = QStringList());
    void stopCurrentTask();

    // 状态查询
    QString getCurrentTaskName() const;
    int getCurrentStepIndex() const;
    int getTotalSteps() const;
    QString getCurrentStepDescription() const;
    AtomicOperation getCurrentOperation() const;

    // 条件判断
    void setCondition(const QString& key, bool value);
    bool getCondition(const QString& key) const;
    void clearConditions();

    // 静态工具方法
    static QString getOperationName(AtomicOperation operation);

signals:
    // 任务执行状态
    void taskStarted(int taskCode, const QString& taskName);
    void taskFinished(int taskCode);   // 任务结束（通用）
    void taskCompleted(int taskCode);  // 任务正常完成
    void taskFailed(int taskCode, const QString& reason);

    // 步骤执行状态
    void stepStarted(int stepIndex, const QString& description);
    void stepCompleted(int stepIndex);
    void stepTimeout(int stepIndex);

    // 操作执行状态
    void operationStarted(AtomicOperation operation, const QStringList& devices);
    void operationCompleted(AtomicOperation operation);

private slots:
    void onStepTimeout();
    void onWaitTimeout();
    void checkStepCompletion();

private:
    void handleTimeout(const QString& timeoutType, const QString& failurePrefix,
                       const QString& skipMessage);
    void executeCurrentStep();
    void executeNextStep();
    bool executeAtomicOperationInternal(const OperationStep& step, QStringList& operatedDevices,
                                        QString& errorMessage);
    bool areAllDevicesIdle(const QStringList& devices) const;
    bool areAllDevicesBusy(const QStringList& devices) const;
    bool checkDeviceCondition(QStringList& completedDevices);  // 检查设备状态条件
    QStringList getDeviceNames() const;
    void cleanupCurrentTask();  // 清理当前任务状态
    void stopAllDevices();      // 停止所有设备

    // 内置任务定义
    void defineBuiltinTasks();
    void defineAnalysisTask();
    void defineSpikeRecoveryTask();

    // 执行状态
    bool m_isRunning;
    CompositeTask m_currentTask;
    int m_currentTaskCode;
    int m_currentStepIndex;
    StepState m_currentStepState;
    QStringList m_operatedDevices;  // 当前步骤中实际操作的设备列表

    // 定时器
    QTimer* m_stepTimer;     // 步骤超时定时器
    QTimer* m_waitTimer;     // 等待超时定时器
    QTimer* m_monitorTimer;  // 设备状态监控定时器

    // 任务定义
    QMap<int, CompositeTask> m_compositeTasks;

    // 条件数据
    QMap<QString, bool> m_conditions;

    // 错误去重
    static QMap<QString, qint64> s_lastErrorTime;  // 错误消息 -> 最后打印时间戳
    static const int ERROR_COOLDOWN_MS = 10000;    // 错误冷却期10秒

    // 静态数据
    static const QMap<AtomicOperation, QString> OPERATION_NAMES;
};

#endif  // TASK_STATE_MACHINE_H